using System;
using System.Collections.Generic;
using System.Linq;
using ArtificialIntelligence.CombatComponent;
using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using XNA_2DFramwork;

namespace City_War_Game
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        
        GraphicsDeviceManager _graphics;
        SpriteBatch spriteBatch;
        private PhysicsSimulator _ps = new PhysicsSimulator(new Vector2(0, 0));
        private PlayerControler PC;

        public Agent Agent1; // cat 1
        public Agent Agent2;

        private Player player; // cat2
        City city;// cat 3

         Building Building1; // cat4
        private Tree tree1; // cat5
        private Tree tree2;
        private Tree tree3;
        private Tree tree4;
        private Tree tree5;
        private Tree tree6;

        private Tree Midtree1;
        private Tree Midtree2;
        private Tree Midtree3;
        private Tree Midtree4;
        private Tree Midtree5;
        private Tree Midtree6;

        private Bullets bullets1; //cat 6
        private Bullets bullets2;

        private InferenceMachine inferenceMachine;
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            //spriteBatch = new SpriteBatch(_graphics.GraphicsDevice);
            VisualObject._lVisualObject = new List<VisualObject>();
            Content.RootDirectory = "Content";
            inferenceMachine = new InferenceMachine(this);
            InferenceMachine._domain.Add(new PathNode(new Vector2(10,10),MovementCommad.Walk ));
            InferenceMachine._domain.Add(new PathNode(new Vector2(10, 30), MovementCommad.Walk));
            

        }
 
        protected override void Initialize()
        {
            _graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;
            _graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;
            _graphics.ApplyChanges();

            #region bullets
            bullets1 = new Bullets(this, 13, 25, new Vector2(700, 700), "Projectile",_graphics.GraphicsDevice,_ps)
                           {
                               Body = { IgnoreGravity = true},
                               Geom =
                                   {
                                       CollisionCategories = CollisionCategory.Cat6,
                                       CollidesWith = CollisionCategory.Cat2,
                                       CollisionResponseEnabled = false
                                   }
                           };
            bullets2 = new Bullets(this, 13, 25, new Vector2(200, 200), "Projectile", _graphics.GraphicsDevice, _ps)
            {
                Body = { IgnoreGravity = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat6,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };
            #endregion
            #region agents
            Agent1 = new Agent(this, 12, 16, new Vector2(900, 200), "soldier-east8",
                          _graphics.GraphicsDevice, _ps)
            {
                Body = { IgnoreGravity = true },
                             
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat1,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            Agent2 = new Agent(this, 12, 16, new Vector2(200, 300), "soldier-east8", _graphics.GraphicsDevice, _ps)
                     {
                         Body =
                             {IgnoreGravity = true},
                             
                        Geom =
                        {
                            CollisionCategories = CollisionCategory.Cat1,
                            CollidesWith = CollisionCategory.Cat2,
                            CollisionResponseEnabled = false
                        }
            };
            #endregion

            Building1 = new Building(this, 105, 125, new Vector2(100, 100), "headquarters", _graphics.GraphicsDevice, _ps)
            {
                Body = { IgnoreGravity = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat4,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };
            
            city = new City(this,3048,2048, new Vector2(0, 0), "Green Background",_graphics.GraphicsDevice,_ps)
                       {
                           Body = {IgnoreGravity = true},
                       Geom =
                           {
                               CollisionCategories = CollisionCategory.Cat3,
                               CollidesWith = CollisionCategory.None,
                               CollisionResponseEnabled = false
                           }
                       };
            #region TreeMiddle
            Midtree1 = new Tree(this, 65, 61, new Vector2(162, 400), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            Midtree2 = new Tree(this, 65, 61, new Vector2(228, 400), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            Midtree3 = new Tree(this, 65, 61, new Vector2(300, 400), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            Midtree4 = new Tree(this, 65, 61, new Vector2(162, 461), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            Midtree5 = new Tree(this, 65, 61, new Vector2(228, 461), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };


            Midtree6 = new Tree(this, 65, 61, new Vector2(300, 461), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };
            #endregion
            #region Trees Bottom

            tree1 = new Tree(this, 65, 61, new Vector2(101, 600), "tree1", _graphics.GraphicsDevice, _ps)
                     {
                         Body = { 
                         IsStatic = true},
                         Geom =
                         {
                             CollisionCategories = CollisionCategory.Cat5,
                             CollidesWith = CollisionCategory.Cat2,
                             CollisionResponseEnabled = false
                         }
                     };

            tree2 = new Tree(this, 65, 61, new Vector2(166, 600), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            tree3 = new Tree(this, 65, 61, new Vector2(231, 600), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };

            tree4 = new Tree(this, 65, 61, new Vector2(101, 661), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };
            
            tree5 = new Tree(this, 65, 61, new Vector2(166, 661), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };


            tree6 = new Tree(this, 65, 61, new Vector2(231, 661), "tree1", _graphics.GraphicsDevice, _ps)
            {
                Body = { IsStatic = true },
                Geom =
                {
                    CollisionCategories = CollisionCategory.Cat5,
                    CollidesWith = CollisionCategory.Cat2,
                    CollisionResponseEnabled = false
                }
            };
            #endregion

            player = new Player(this, new Vector2(200, 300),80, 50, "soldier-hit-northwest", _graphics.GraphicsDevice, _ps)
                         {
                             Body = { IgnoreGravity = true, IsStatic = true },
                             Geom =
                             {
                                 CollisionCategories = CollisionCategory.Cat2,
                                 CollidesWith = CollisionCategory.Cat3,
                                 CollisionResponseEnabled = false
                             }
                         };

            PC = new PlayerControler(this,player);


            //inferenceMachine.CreateSchedule(ScheduleType.GetObject);
            //inferenceMachine.CreateSchedule(ScheduleType.GetWeapon);
            InferenceMachine._missions.Add(inferenceMachine.ScheduleGetObject);
            InferenceMachine._missions.Add(inferenceMachine.ScheduleGetObject);
            
            VisualObject._lVisualObject.Add(inferenceMachine);

            VisualObject._lVisualObject.Add(city);

            VisualObject._lVisualObject.Add(tree1);
            VisualObject._lVisualObject.Add(tree2);
            VisualObject._lVisualObject.Add(tree3);
            VisualObject._lVisualObject.Add(tree4);
            VisualObject._lVisualObject.Add(tree5);
            VisualObject._lVisualObject.Add(tree6);

            VisualObject._lVisualObject.Add(Midtree1);
            VisualObject._lVisualObject.Add(Midtree2);
            VisualObject._lVisualObject.Add(Midtree3);
            VisualObject._lVisualObject.Add(Midtree4);
            VisualObject._lVisualObject.Add(Midtree5);
            VisualObject._lVisualObject.Add(Midtree6);

            VisualObject._lVisualObject.Add(bullets1);
            VisualObject._lVisualObject.Add(bullets2);

            VisualObject._lVisualObject.Add(Building1);
            
            VisualObject._lVisualObject.Add(Agent1);
            VisualObject._lVisualObject.Add(Agent2);
            
            VisualObject._lVisualObject.Add(player);

            

            inferenceMachine._LAgents.Add(Agent1);
            inferenceMachine._LAgents.Add(Agent2);            

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);


            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            foreach (VisualObject obj in VisualObject._lVisualObject)
                obj.Update();
            _ps.Update(gameTime.ElapsedGameTime.Milliseconds * .001f);
            

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            
            foreach (VisualObject obj in VisualObject._lVisualObject)
                obj.Draw();
            
            base.Draw(gameTime);
        }
    }
}
